package com.shlh.saas.controller;

import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shlh.saas.common.Result;
import com.shlh.saas.common.UserContext;
import com.shlh.saas.entity.UserBalance;
import com.shlh.saas.entity.company.Company;
import com.shlh.saas.service.UserBalanceService;
import com.shlh.saas.service.WorkbenchStatsService;
import com.shlh.saas.service.company.CompanyService;
import com.shlh.saas.service.ExportRecordService;
import com.shlh.saas.util.FileUtils;
import com.shlh.saas.util.ExcelUtils;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.ArrayList;
import java.util.Arrays;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 全球企业库控制器
 */
@RestController
@RequestMapping("/enterprises")
@Slf4j
public class GlobalEnterpriseController {

    @Autowired
    private CompanyService companyService;

    @Autowired
    private UserBalanceService userBalanceService;

    @Autowired
    private WorkbenchStatsService workbenchStatsService;

    @Autowired
    private ExportRecordService exportRecordService;

    /**
     * 获取所有全球企业库数据
     */
    @GetMapping("/global")
    public Result getAllGlobalEnterprises(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size) {
        log.info("获取全球企业库数据，页码：{}，每页条数：{}", page, size);

        try {
            Long userId = UserContext.getUserId();

            // 获取真实数据总量（不受任何限制）
            long realTotalCount = companyService.countGlobalEnterprises();
            log.info("全球企业库真实数据总量: {} 条记录", realTotalCount);

            // 第一页不扣除额度，免费查看
            if (page == 1) {
                Page<Company> enterprises = companyService.getGlobalEnterprisesPage(page, size);

                // 增加搜索次数统计
                workbenchStatsService.incrementEnterpriseSearchCount(userId);

                Map<String, Object> result = getMap(enterprises);

                // 返回真实的数据总量，不受任何限制
                result.put("total", realTotalCount);
                result.put("realCount", realTotalCount); // 添加明确的真实数量字段

                return Result.success(result);
            } else {
                // 检查用户余额
                UserBalance userBalance = userBalanceService.getByUserId(userId);
                if (userBalance == null || userBalance.getViewRecordsRemaining() < size) {
                    return Result.error("您的查看记录余额不足，请充值后再查看");
                }

                // 查询数据
                Page<Company> enterprises = companyService.getGlobalEnterprisesPage(page, size);

                // 扣除用户查看记录余额
                userBalanceService.deductViewRecords(userId, Math.toIntExact(enterprises.getSize()));

                // 增加搜索次数统计
                workbenchStatsService.incrementEnterpriseSearchCount(userId);

                Map<String, Object> result = getMap(enterprises);

                // 返回真实的数据总量，不受任何限制
                result.put("total", realTotalCount);
                result.put("realCount", realTotalCount); // 添加明确的真实数量字段

                return Result.success(result);
            }
        } catch (Exception e) {
            log.error("获取全球企业库数据失败", e);
            return Result.error("获取全球企业库数据失败: " + e.getMessage());
        }
    }

    @NotNull
    private static Map<String, Object> getMap(Page<Company> enterprises) {
        Map<String, Object> result = new HashMap<>();
        result.put("records", enterprises.getRecords());
        result.put("size", enterprises.getSize());
        result.put("current", enterprises.getCurrent());
        // 注意：total字段将在调用方法中单独设置，确保返回真实的数据总量
        return result;
    }

    /**
     * 根据条件搜索全球企业库数据
     */
    @GetMapping("/global/search")
    public Result searchGlobalEnterprises(
            @RequestParam(required = false) String companyName,
            @RequestParam(required = false) String firstName,
            @RequestParam(required = false) String lastName,
            @RequestParam(required = false) String zipcode,
            @RequestParam(required = false) String country,
            @RequestParam(required = false) String city,
            @RequestParam(required = false) String department,
            @RequestParam(required = false) String occupation,
            @RequestParam(required = false) String industry,
            @RequestParam(required = false) String employee,
            @RequestParam(required = false) String reveneu,
            @RequestParam(required = false) String state,
            @RequestParam(required = false) String hasContact,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size) {
        log.info("搜索全球企业库数据，公司名称：{}，名：{}，姓：{}，邮编：{}，国家：{}，城市：{}，部门：{}，职业：{}，行业：{}，员工规模：{}，收入规模：{}，所在州：{}，联系方式：{}，页码：{}，每页条数：{}",
                companyName, firstName, lastName, zipcode, country, city, department, occupation, industry, employee, reveneu, state, hasContact, page, size);
        try {
            Long userId = UserContext.getUserId();

            long realTotalCount = companyService.countSearchGlobalEnterprises(companyName,country, city, industry, employee, reveneu, firstName, lastName, zipcode, department, occupation, state, hasContact);

            // 第一页不扣除额度，免费查看
            if (page == 1) {
                Page<Company> enterprises = companyService.searchGlobalEnterprisesPage(
                        companyName, firstName, lastName, country, city, industry, employee, reveneu, zipcode, department, occupation, state, hasContact, page, size);

                // 增加搜索次数统计
                workbenchStatsService.incrementEnterpriseSearchCount(userId);

                Map<String, Object> result = getMap(enterprises);

                result.put("total", realTotalCount);
                result.put("realCount", realTotalCount); // 添加明确的真实数量字段

                return Result.success(result);
            } else {
                // 检查用户余额
                UserBalance userBalance = userBalanceService.getByUserId(userId);
                if (userBalance == null || userBalance.getViewRecordsRemaining() < size) {
                    return Result.error("您的查看记录余额不足，请充值后再查看");
                }

                // 查询数据
                Page<Company> enterprises = companyService.searchGlobalEnterprisesPage(
                        companyName, firstName, lastName, country, city, industry, employee, reveneu, zipcode, department, occupation, state, hasContact, page, size);

                // 扣除用户查看记录余额
                userBalanceService.deductViewRecords(userId, Math.toIntExact(enterprises.getSize()));

                // 增加搜索次数统计
                workbenchStatsService.incrementEnterpriseSearchCount(userId);

                Map<String, Object> result = getMap(enterprises);

                result.put("total", realTotalCount);
                result.put("realCount", realTotalCount); // 添加明确的真实数量字段

                return Result.success(result);
            }
        } catch (Exception e) {
            log.error("搜索全球企业库数据失败", e);
            return Result.error("搜索全球企业库数据失败: " + e.getMessage());
        }
    }

    /**
     * 获取符合条件的记录总数
     */
    @PostMapping("/global/count")
    public Result countGlobalEnterprises(@RequestBody Map<String, Object> params) {
        log.info("计算符合条件的全球企业数量，参数: {}", params);

        String companyName = (String) params.getOrDefault("companyName", null);
        String country = (String) params.getOrDefault("country", null);
        String city = (String) params.getOrDefault("city", null);
        String industry = (String) params.getOrDefault("industry", null);
        String employee = (String) params.getOrDefault("employee", null);
        String reveneu = (String) params.getOrDefault("reveneu", null);
        String firstName = (String) params.getOrDefault("firstName", null);
        String lastName = (String) params.getOrDefault("lastName", null);
        String zipcode = (String) params.getOrDefault("zipcode", null);
        String department = (String) params.getOrDefault("department", null);
        String occupation = (String) params.getOrDefault("occupation", null);
        String state = (String) params.getOrDefault("state", null);
        String hasContact  = (String) params.getOrDefault("hasContact ", null);

        long count =
                companyService.countSearchGlobalEnterprises(companyName, country, city, industry, employee, reveneu, firstName, lastName, zipcode, department, occupation, state, hasContact);

        // 限制最大返回数量为5万（符合ES的max_result_window默认限制）
        if (count > 50000) {
            count = 50000;
        }

        Map<String, Object> result = new HashMap<>();
        result.put("count", count);
        return Result.success(result);
    }

    /**
     * 导出全球企业数据
     */
    @PostMapping("/global/export")
    public void exportGlobalEnterprises(
            HttpServletResponse response,
            @RequestBody(required = false) Map<String, Object> params,
            @RequestParam(required = true) Integer exportCount,
            @RequestParam(required = false) String selectedFields,
            @RequestParam(required = false, defaultValue = "zh") String language) {
        log.info("导出全球企业数据，参数: {}, 导出数量: {}, 选中字段: {}, 语言: {}", params, exportCount, selectedFields, language);
        
        // 设置响应头部信息，防止客户端浏览器超时
        response.setHeader("Connection", "Keep-Alive");
        response.setHeader("Proxy-Connection", "Keep-Alive");
        
        // 明确设置Content-Type为Excel文件格式
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition", "attachment; filename=global-enterprise-export.xlsx");
        
        try {
            // 获取当前用户ID
            Long userId = UserContext.getUserId();

            // 检查用户余额
            UserBalance userBalance = userBalanceService.getByUserId(userId);
            if (userBalance == null || userBalance.getExportQuotaRemaining() < exportCount) {
                response.setContentType("application/json;charset=UTF-8");
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                response.getWriter().write("{\"message\":\"您的导出次数余额不足，请充值后再导出\"}");
                return;
            }

            // 限制最大导出数量为5万（符合ES的max_result_window默认限制）
            if (exportCount > 50000) {
                exportCount = 50000;
            }

            // 根据筛选条件查询数据（两阶段查询模式）
            params.put("limit", exportCount);
            log.info("开始两阶段查询导出数据：第一阶段从ES获取标识信息，第二阶段从数据库获取完整数据");
            log.info("导出参数：size={}, 这个值应该不超过ES的max_result_window限制(50000)", exportCount);

            // 改为使用批量处理和多线程优化的查询方法
            List<Company> enterprises = companyService.searchGlobalEnterprisesForExportOptimized(params);

            log.info("两阶段查询完成，最终获取到符合条件的企业数据: {} 条", enterprises.size());

            if (enterprises.isEmpty()) {
                response.setContentType("application/json;charset=UTF-8");
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                response.getWriter().write("{\"message\":\"没有找到符合条件的数据\"}");
                return;
            }

            // 扣除用户导出次数余额
            userBalanceService.deductExportQuota(userId, enterprises.size());

            // 增加导出次数统计
            workbenchStatsService.incrementEnterpriseExportCount(userId, enterprises.size());

            // 处理字段选择（支持国际化）
            Map<String, String> fieldMapping = createFieldMapping(language);
            String[] selectedFieldArray;
            String[] selectedColumnNames;

            if (selectedFields != null && !selectedFields.trim().isEmpty()) {
                // 解析选中的字段
                String[] requestedFields = selectedFields.split(",");
                List<String> validFields = new ArrayList<>();
                List<String> validColumnNames = new ArrayList<>();

                for (String field : requestedFields) {
                    field = field.trim();
                    if (fieldMapping.containsKey(field)) {
                        validFields.add(field);
                        validColumnNames.add(fieldMapping.get(field));
                    } else {
                        log.warn("无效的字段名: {}", field);
                    }
                }

                if (validFields.isEmpty()) {
                    response.setContentType("application/json;charset=UTF-8");
                    response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                    response.getWriter().write("{\"message\":\"没有有效的字段被选中，请至少选择一个有效字段\"}");
                    return;
                }

                selectedFieldArray = validFields.toArray(new String[0]);
                selectedColumnNames = validColumnNames.toArray(new String[0]);
                log.info("有效字段数量: {}, 字段列表: {}", validFields.size(), validFields);
            } else {
                // 如果没有指定字段，使用默认字段
                selectedFieldArray = getDefaultFields();
                selectedColumnNames = getDefaultColumnNames(language);
                log.info("使用默认字段进行导出");
            }

            // 自动确定标红字段（重要字段）
            String[] highlightFieldArray = getHighlightFields(selectedFieldArray);
            log.info("自动标红字段数量: {}, 标红字段列表: {}", highlightFieldArray.length, Arrays.toString(highlightFieldArray));

            // 设置导出文件名（支持国际化）
            String fileNamePrefix = "en".equals(language) ? "Global_Enterprise_Data" : "全球企业数据";
            String fileName = fileNamePrefix + "_" + System.currentTimeMillis() + ".xlsx";

            // 获取当前时间戳作为文件名一部分
            String filePath = "/export/" + fileName;

            // 计算文件大小（以KB为单位）
            String fileSize = FileUtils.estimateExcelSize(enterprises.size()) + "KB";

            // 保存导出记录
            exportRecordService.addExportRecord(
                    userId,
                    fileName,
                    "global-enterprise", // 数据来源
                    fileSize,
                    enterprises.size(),
                    filePath
            );

            // 使用优化版本的导出方法（使用临时文件和流式处理）
            if (enterprises.size() > 10000) {
                // 大数据量使用优化版导出方法
                log.info("数据量大于10000，使用优化版导出方法");
                ExcelUtils.exportExcelWithHighlightOptimized(response, enterprises, fileName,
                        selectedColumnNames, selectedFieldArray, highlightFieldArray);
            } else {
                // 小数据量使用普通导出方法
            ExcelUtils.exportExcelWithHighlight(response, enterprises, fileName,
                    selectedColumnNames, selectedFieldArray, highlightFieldArray);
            }
            log.info("成功导出全球企业数据，包含字段: {}，自动标红字段: {}",
                    Arrays.toString(selectedColumnNames), Arrays.toString(highlightFieldArray));

        } catch (Exception e) {
            log.error("导出全球企业数据失败", e);
            try {
                if (!response.isCommitted()) {
                response.reset();
                response.setContentType("application/json;charset=UTF-8");
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.getWriter().write("{\"message\":\"导出数据失败: " + e.getMessage() + "\"}");
                } else {
                    log.warn("无法发送错误响应，因为响应已经提交");
                }
            } catch (IOException ex) {
                log.error("写入错误响应失败", ex);
            }
        }
    }

    /**
     * 查看企业数据详细信息
     *
     * @param mt 企业ID
     * @return 企业详细信息
     */
    @GetMapping("/global/detail")
    public Result<Map<String, String>> detailGlobalEnterprises(
            @RequestParam(required = false) String enterpriseId,
            @RequestParam(required = false) String mt) {

        try {

            // 验证参数
            if (enterpriseId == null ) {
                return Result.error("请提供企业标识符");
            }
            
            log.info("查看企业详情，企业ID: {}", enterpriseId);

            // 检查用户，获取用户ID
            Long userId = UserContext.getUserId();
            log.info("当前用户ID: {}", userId);

            // 检查用户余额
            UserBalance userBalance = userBalanceService.getByUserId(userId);
            if (userBalance == null || userBalance.getViewRecordsRemaining() < 1) {
                return Result.error("您的查看记录余额不足，请充值后再查看");
            }

            // 查询企业信息
            log.info("开始查询企业信息，ID: {}", enterpriseId);
            Company company = companyService.getDetailByTableAndId(enterpriseId, mt);
            
            if (company == null){
                log.warn("未找到企业信息，ID: {}", enterpriseId);
                return Result.error("未找到企业信息");
            }
            
            log.info("成功获取企业信息: {}", company);

            // 扣减用户余额
            userBalanceService.deductViewRecords(userId, 1);
            log.info("已扣减用户查看记录余额");

            // 根据信息类型返回相应数据
            Map<String, String> result = new HashMap<>();
            result.put("email", company.getEmail());
            result.put("phone", company.getPhone());
            result.put("mobile", company.getMobile());
            result.put("webAddress", company.getWebAddress());
            
            log.info("返回企业详情数据成功");
            return Result.success(result);
        } catch (Exception e){
            log.error("查看企业详情失败，企业ID: {}, 错误: {}", enterpriseId, e.getMessage(), e);
            return Result.error("查看详情失败：" + e.getMessage());
        }
    }

    /**
     * 创建字段映射关系（支持国际化）
     * @param language 语言代码（zh/en）
     * @return 字段名到对应语言标题的映射
     */
    private Map<String, String> createFieldMapping(String language) {
        Map<String, String> fieldMapping = new HashMap<>();
        boolean isEnglish = "en".equals(language);

        fieldMapping.put("companyName", isEnglish ? "Company Name" : "企业名称");
        fieldMapping.put("country", isEnglish ? "Country" : "国家");
        fieldMapping.put("primaryCity", isEnglish ? "City" : "城市");
        fieldMapping.put("primaryState", isEnglish ? "State/Province" : "州/省");
        fieldMapping.put("industry", isEnglish ? "Industry" : "行业");
        fieldMapping.put("subIndustry", isEnglish ? "Sub Industry" : "子行业");
        fieldMapping.put("employee", isEnglish ? "Employee Size" : "员工规模");
        fieldMapping.put("reveneu", isEnglish ? "Revenue Size" : "收入规模");
        fieldMapping.put("firstName", isEnglish ? "First Name" : "名字");
        fieldMapping.put("middleName", isEnglish ? "Middle Name" : "中间名");
        fieldMapping.put("lastName", isEnglish ? "Last Name" : "姓");
        fieldMapping.put("title", isEnglish ? "Title" : "职位");
        fieldMapping.put("phone", isEnglish ? "Phone" : "电话");
        fieldMapping.put("mobile", isEnglish ? "Mobile" : "手机号");
        fieldMapping.put("email", isEnglish ? "Email" : "邮箱");
        fieldMapping.put("mailingAddress", isEnglish ? "Address" : "地址");
        fieldMapping.put("zipCode", isEnglish ? "Zip Code" : "邮编");
        fieldMapping.put("webAddress", isEnglish ? "Website" : "网站");
        return fieldMapping;
    }

    /**
     * 获取默认字段列表
     * @return 默认字段数组
     */
    private String[] getDefaultFields() {
        return new String[]{
            "companyName", "country", "primaryCity", "primaryState",
            "industry", "subIndustry", "employee", "reveneu",
            "firstName", "middleName", "lastName", "title", "phone", "email",
            "mailingAddress", "zipCode", "webAddress"
        };
    }

    /**
     * 获取默认列名列表（支持国际化）
     * @param language 语言代码（zh/en）
     * @return 默认列名数组
     */
    private String[] getDefaultColumnNames(String language) {
        boolean isEnglish = "en".equals(language);
        if (isEnglish) {
            return new String[]{
                "Company Name", "Country", "City", "State/Province", "Industry", "Sub Industry",
                "Employee Size", "Revenue Size", "First Name", "Middle Name", "Last Name", "Title",
                "Phone", "Email", "Address", "Zip Code", "Website"
            };
        } else {
            return new String[]{
                "企业名称", "国家", "城市", "州/省", "行业", "子行业",
                "员工规模", "收入规模", "名字", "中间名", "姓", "职位",
                "电话", "邮箱", "地址", "邮编", "网站"
            };
        }
    }

    /**
     * 获取需要标红的重要字段列表
     * @param selectedFields 用户选中的字段列表
     * @return 需要标红的字段数组（只包含用户选中的重要字段）
     */
    private String[] getHighlightFields(String[] selectedFields) {
        // 定义重要字段列表（需要标红的字段）
        String[] importantFields = {
            "companyName",    // 企业名称
            "email",          // 邮箱
            "phone",          // 电话
            "webAddress"      // 网站
        };

        List<String> highlightFields = new ArrayList<>();
        Set<String> selectedFieldSet = new HashSet<>(Arrays.asList(selectedFields));

        // 只有当重要字段被用户选中时，才加入标红列表
        for (String importantField : importantFields) {
            if (selectedFieldSet.contains(importantField)) {
                highlightFields.add(importantField);
            }
        }

        return highlightFields.toArray(new String[0]);
    }

    /**
     * 查询企业城市数据信息
     *
     * @return 企业城市信息
     */
    @GetMapping("/global/cities")
    public Result<List<String>> searchCities(
            @RequestParam(required = false) String keyword) {
        List<String> cities = companyService.searchCities(keyword);

        return Result.success(cities);
    }

    /**
     * 查询企业行业数据信息
     *
     * @return 企业行业信息
     */
    @GetMapping("/global/industries")
    public Result<List<String>> searchIndustries(
            @RequestParam(required = false) String keyword) {
        List<String> industries = companyService.searchIndustries(keyword);

        return Result.success(industries);
    }

    /**
     * 查询企业行业数据信息
     *
     * @return 企业行业信息
     */
    @GetMapping("/global/departments")
    public Result<List<String>> searchDepartments(
            @RequestParam(required = false) String keyword) {
        List<String> departments = companyService.searchDepartments(keyword);

        return Result.success(departments);
    }

    /**
     * 查询企业行业数据信息
     *
     * @return 企业行业信息
     */
    @GetMapping("/global/occupations")
    public Result<List<String>> searchOccupations(
            @RequestParam(required = false) String keyword) {
        List<String> occupations = companyService.searchOccupations(keyword);

        return Result.success(occupations);
    }

}